using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;
using umbraco.cms.businesslogic.media;
using Commerce.Promotions;
using Commerce.Common;
using System.Text;


namespace CommerceForUmbraco.usercontrols
{
    public partial class singleProduct : System.Web.UI.UserControl
    {
        #region Properties

        public string ProductName;
        public string SKU;
        public string ProductID;
        public string ShortDescription;
        public string Features;
        public decimal OurPrice;
        public decimal RetailPrice;
        public string ImageFile = "";
        public string ImageFileThumb = "";
        public string ShippingEstimate;
        public string Rating;
        public int ImageID;

        protected int productID;
        protected string productSku;
        protected Guid productGUID;

        private Commerce.Common.Product product = null;
        protected ProductDiscount discount;

        private string _PropProductId;

        public string PropProductId 
        {
            get { return _PropProductId; }
            set { _PropProductId = value; }
        }

        public int DefaultCrossSellImage
        {
            get;
            set;
        }

        private bool _DontRedirectToCart;

        public bool DontRedirectToCart
        {
            get
            {
                return _DontRedirectToCart;
            }
            set
            {
                _DontRedirectToCart = value;
            }
        }

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                string sProductGUID = "";

                if (IsGUID(PropProductId))
                    sProductGUID = PropProductId;

                if (int.TryParse(PropProductId, out productID) == false)
                    productID = 0;

                //productSku = Commerce.Common.Utility.UnwindRewriteParam(PropProductId);
                productSku = PropProductId;

                if (sProductGUID != string.Empty)
                {
                    productGUID = new Guid(sProductGUID);
                    product = ProductController.GetProductDeepByGUID(productGUID);
                }
                else if (productID != 0)
                {
                    product = ProductController.GetProductDeep(productID);
                }
                else if (productSku != string.Empty)
                {
                    product = ProductController.GetProductDeepByUrlFriendly(productSku);
                    //product = ProductController.GetProductDeepByName(productSku);
                    //product = ProductController.GetProductDeep(productSku);
                }

                //make sure we have a product
                TestCondition.IsTrue(product.IsLoaded, "Invalid url/product id");

                if( product.Status == ProductStatus.Inactive )
                {
                    Response.Redirect("/");
                }

                //set the page variables
                productID = product.ProductID;
                productSku = product.Sku;
                ProductName = product.ProductName;
                RetailPrice = product.RetailPrice;
                OurPrice = product.OurPrice;
                // get the image URL from the Umbraco Node id
                if (!String.IsNullOrEmpty(product.DefaultImage.Trim()))
                {
                    ImageID = int.Parse(product.DefaultImage);
                    int mediaID;
                    if (Int32.TryParse(product.DefaultImage, out mediaID))
                    {
                        Media m = new Media(mediaID);
                        //$mediaItem/crops/crops/crop[@name='Main Product Image']/@url

                        if (m.getProperty("crops").Value.ToString().Trim().Length > 0)
                        {
                            string imagecrops = m.getProperty("crops").Value.ToString();

                            // Regex to pull out crop out of xml
                            string pattern = @"<crop name=""Main Product Image"".+url=""(?'url'.*_Main Product Image\.jpg?)"" />";
                            MatchCollection matches = Regex.Matches(imagecrops, pattern);

                            string imageloc = "";

                            foreach (Match match in matches)
                            {
                                if (match.Groups["url"].Success == true)
                                {
                                    imageloc = match.Groups["url"].Value;
                                }
                            }

                            ImageFile = Server.UrlEncode(imageloc);

                            
                            // Regex to pull out crop out of xml
                            pattern = @"<crop name=""Product Image Thumbnail"".+url=""(?'url'.*_Product Image Thumbnail\.jpg?)"" />";
                            matches = Regex.Matches(imagecrops, pattern);

                            imageloc = "";

                            foreach (Match match in matches)
                            {
                                if (match.Groups["url"].Success == true)
                                {
                                    imageloc = match.Groups["url"].Value;
                                }
                            }

                            ImageFileThumb = Server.UrlEncode(imageloc);
                        } 
                        else if (m.getProperty("umbracoFile").Value.ToString().Trim().Length > 0)
                        {
                            //ImageFile = Server.UrlEncode(m.getProperty("umbracoFile").Value.ToString());
                            ImageFile = m.getProperty("umbracoFile").Value.ToString().Trim();
                        }
                        else
                        {
                            ImageMainPanel.Visible = false;
                        }

                        //else
                        //{
                        //    Media tempDefault = new Media(DefaultImage);
                        //    dr["defaultImage"] = Server.UrlEncode(tempDefault.getProperty("umbracoFile").Value.ToString());
                        //}
                        //ImageFile = m.getProperty("umbracoFile").Value.ToString();
                    }
                    else
                    {
                        ImageMainPanel.Visible = false;
                    }
                }
                else
                {
                    //ImagesPanel.Visible = false;
                    ImageMainPanel.Visible = false;
                }
                ShippingEstimate = product.ShippingEstimate;
                OurPrice = product.OurPrice;
                ShortDescription = product.ShortDescription;

                if (product.Status != ProductStatus.Active)
                {
                    statusLabelPanel.Visible = true;
                    var statusStr = product.Status.ToString();
                    System.Text.RegularExpressions.Regex reg = new Regex("([A-Z]{1})");
                    statusStr = reg.Replace(statusStr, " $1");
                    statusLabel.Text = statusStr;
                }

                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                //CategoryCollection prodCategories = CategoryController.GetByProductID(product.ProductID);
                CategoryCollection prodCategories = product.GetCategoryCollection();
                //statusLabel.Text += " -- " + prodCategories.Count.ToString();
                if (prodCategories != null)
                {
                    if (prodCategories.Count > 0)
                    {
                        string comma = "";
                        foreach (Category cat in prodCategories)
                        {
                            int catId = 0;
                            if (cat.ParentIDHasValue)
                            {
                                catId = cat.ParentID;
                            }
                            //statusLabel.Text += String.Format("<p>Parent ID: {0} -- {1}</p>", catId.ToString(), cat.ShortDescription);

                            if( catId > 0 )
                            {
                                Category parentCat = Category.FetchByID(catId);
                                if (parentCat != null)
                                {
                                    sb.AppendFormat("{0}<a id=\"{3}\" href=\"{2}\">{1}</a>", comma, cat.CategoryName, Commerce.Common.Utility.GetSubcategoryRewriterUrl("sub", cat.UrlFriendly, parentCat.UrlFriendly, ""), catId);
                                }
                                else
                                {
                                    sb.AppendFormat("{0}<a id=\"{3}\" href=\"{2}\">{1}</a>", comma, cat.CategoryName, Commerce.Common.Utility.GetRewriterUrl("category", cat.UrlFriendly, ""), catId);
                                }
                            }
                            else
                            {
                                sb.AppendFormat("{0}<a id=\"{3}\" href=\"{2}\">{1}</a>", comma, cat.CategoryName, Commerce.Common.Utility.GetRewriterUrl("category", cat.UrlFriendly, ""), catId);
                            }

                            //                    sb.AppendFormat("{0}<a href=\"{2}\">{1}</a>", comma, cat.CategoryName, Commerce.Common.Utility.GetRewriterUrl("subcategory", cat.UrlFriendly, ""));
                            comma = ", ";
                        }
                    }
                }
                categoriesPH.Controls.Add(new LiteralControl(sb.ToString()));

                ImageCollection prodImages = ProductController.GetImages(product.ProductID);
                //statusLabel.Text += " -- " + prodImages.Count.ToString();
                if (prodImages.Count > 0)
                {
                    DataTable dt = prodImages.ToDataTable();
                    Hashtable imgHT = new Hashtable();
                    DataTable newDT = new DataTable();
                    newDT.Columns.Add("imageFile");
                    newDT.Columns.Add("caption");
                    newDT.Columns.Add("imageID");
                    newDT.Columns.Add("styles");

                    DataTable newBigDT = new DataTable();
                    newBigDT.Columns.Add("imageFile");
                    newBigDT.Columns.Add("caption");
                    newBigDT.Columns.Add("imageID");
                    newBigDT.Columns.Add("styles");

                    newDT.Rows.Add(ImageFileThumb, ProductName, ImageID, "");
                    newBigDT.Rows.Add(ImageFile, ProductName, ImageID, "");
                    imgHT.Add(ImageID, ImageFile);

                    foreach (DataRow dr in dt.Rows)
                    {
                        int mediaId;
                        if ( Int32.TryParse(dr["imageFile"].ToString(), out mediaId) )
                        {
                            Media temp = new Media(mediaId);

                            //$mediaItem/crops/crops/crop[@name='Product Image Thumbnail']/@url

                            string bigImageFile = "";
                            if (temp.getProperty("crops").Value.ToString().Trim().Length > 0)
                            {
                                string imagecrops = temp.getProperty("crops").Value.ToString();

                                // Regex to pull out crop out of xml
                                string pattern = @"<crop name=""Product Image Thumbnail"".+url=""(?'url'.*_Product Image Thumbnail\.jpg?)"" />";
                                MatchCollection matches = Regex.Matches(imagecrops, pattern);

                                string imageloc = "";

                                foreach (Match match in matches)
                                {
                                    if (match.Groups["url"].Success == true)
                                    {
                                        imageloc = match.Groups["url"].Value;
                                    }
                                }

                                dr["imageFile"] = Server.UrlEncode(imageloc);



                                // Regex to pull out big image crop out of xml
                                pattern = @"<crop name=""Main Product Image"".+url=""(?'url'.*_Main Product Image\.jpg?)"" />";
                                matches = Regex.Matches(imagecrops, pattern);

                                imageloc = "";

                                foreach (Match match in matches)
                                {
                                    if (match.Groups["url"].Success == true)
                                    {
                                        imageloc = match.Groups["url"].Value;
                                    }
                                }

                                bigImageFile = Server.UrlEncode(imageloc);
                            }
                            else
                            {
                                dr["imageFile"] = temp.getProperty("umbracoFile").Value.ToString().Trim();
                                bigImageFile = temp.getProperty("umbracoFile").Value.ToString().Trim();
                            }

                            int width = 0;
                            if (Int32.TryParse(temp.getProperty("umbracoWidth").Value.ToString(), out width))
                            {
                                if (!imgHT.ContainsKey(mediaId) && width > 100)
                                {
                                    newDT.Rows.Add(dr["imageFile"], dr["caption"], mediaId, "display: none;");
                                    newBigDT.Rows.Add(bigImageFile, dr["caption"], mediaId, "display: none;");
                                    imgHT.Add(mediaId, dr["imageFile"]);
                                }
                            }
                        }
                    }

                    ProductImages.DataSource = newDT;
                    ProductImages.DataBind();

                    ProductBigImages.DataSource = newBigDT;
                    ProductBigImages.DataBind();
                }
                else
                {
                    DataTable newDT = new DataTable();
                    newDT.Columns.Add("imageFile");
                    newDT.Columns.Add("caption");
                    newDT.Columns.Add("imageID");
                    newDT.Columns.Add("styles");

                    newDT.Rows.Add(ImageFile, ProductName, ImageID, "");

                    ProductBigImages.DataSource = newDT;
                    ProductBigImages.DataBind();

                    ImageThumbnailsPanel.Visible = false;
                }

                // set the productID for cross sells
                CrossSellDisplay.DefaultImage = DefaultCrossSellImage;
                CrossSellDisplay.relatedProductID = productID.ToString();
                CrossSellDisplay.LoadCrossSells();

                //statusLabel.Text = String.Format("<p><strong>Attributes</strong>: {0}</p>", product.Attributes.Count);
                // Product Options - JASON added Nov. 2010
                AttributeController attrController = new AttributeController();
                Commerce.Common.AttributeCollection attributes = attrController.FetchByQuery( new SubSonic.Query("CSK_Store_Attribute").WHERE("productID",SubSonic.Comparison.Equals,product.ProductID) );

                if (attributes.Count > 0)
                {
                    StringBuilder attrHtml = new StringBuilder();

                    foreach (Commerce.Common.Attribute attr in attributes)
                    {
                        attrHtml.Append("<tr><td class=\"name\">");
                        attrHtml.AppendFormat("{0}:</td>", attr.AttributeTemplate.Description);

                        attrHtml.Append("<td>");
                        attrHtml.Append(GetAttributeSelectionsHtml(attr));
                        attrHtml.Append("</td></tr>");
                    }

                    AttributesPlaceholder.Controls.Add(new LiteralControl(attrHtml.ToString()));
                }
                
            }
            catch (Exception ex)
            {
                statusLabel.Text = String.Format("ERROR: {0}<br/>CALL STACK: {1}<br />SOURCE: {2}", ex.Message, ex.StackTrace, ex.Source);
                if (ex.InnerException != null)
                {
                    statusLabel.Text = String.Format("{0}<br />INNER: {1}<br />INNER STACK: {2}", statusLabel.Text, ex.InnerException.Message, ex.InnerException.StackTrace);
                }
            }

        }

        protected string GetAttributeSelectionsHtml(Commerce.Common.Attribute attribute)
        {
            StringBuilder sb = new StringBuilder();

            AttributeTemplate template = attribute.AttributeTemplate;
            AttributeItemCollection options;

            switch (template.AttributeTypeID)
            {
                case (int)AttributeType.MultipleSelection:
                    sb.AppendFormat("<fieldset id=\"{0}|{1}\" name=\"{0}\" class=\"productOption MultipleSelection\"><ul class=\"fields\">", template.AttributeName, attribute.ProductAttributeID);

                    options = template.AttributeItemRecords();
                    options.Sort("SortOrder", true);
                    foreach (AttributeItem opt in options)
                    {
                        sb.AppendFormat("<li class=\"field\"><input id=\"{0}\" type=\"checkbox\" value=\"{0}\" /><label for=\"{0}\">{1}</label></li>", opt.AttributeItemId, opt.FormattedValue());
                    }

                    sb.Append("</ul></fieldset>");
                    break;

                case (int)AttributeType.SingleSelection:
                    sb.AppendFormat("<select id=\"{0}|{1}\" name=\"{0}\" class=\"productOption SingleSelection\">", template.AttributeName, attribute.ProductAttributeID);

                    options = template.AttributeItemRecords();
                    options.Sort("SortOrder", true);
                    foreach (AttributeItem opt in options)
                    {
                        sb.AppendFormat("<option value=\"{0}\">{1}</option>", opt.AttributeItemId, opt.FormattedValue());
                    }

                    sb.Append("</select>");
                    break;

                case (int)AttributeType.UserInput:
                    sb.AppendFormat("<input id=\"{0}|{1}\" name=\"{0}\" class=\"productOption UserInput\" type=\"text\" />", template.AttributeName, attribute.ProductAttributeID);
                    break;
            }

            return sb.ToString();
        }

        // TODO: Add support for Options
        protected decimal GetDiscountedPrice()
        {
            decimal dOut = OurPrice;

            //get the adjusted price from the Promo service
            ProductDiscount discount = PromotionService.GetProductDiscount(productID);

            if (discount != null)
                dOut = discount.DiscountedPrice;

            return dOut;

        }

        // TODO: Add support for Options
        protected void AddToCart_Click(object sender, EventArgs e)
        {
            Commerce.Common.Product prod = new Commerce.Common.Product(productID);
            prod.Quantity = int.Parse(qtyToAdd.Text);
            OrderController.AddItem(prod);

            if (DontRedirectToCart)
            {
                CartEvent.Add(productID, int.Parse(qtyToAdd.Text));

            }
            else
            {
                // send to cart page
                Response.Redirect(Utility.GetCartUrl(), true);
            }

        }

        public static bool IsGUID(string expression)
        {
            if (expression != null)
            {
                Regex guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");

                return guidRegEx.IsMatch(expression);
            }
            return false;
        }
    }
}